﻿using Elsa.Mediator.Contracts;
using Elsa.Workflows.Notifications;

namespace ElsaDemo.ActivityAop
{
    /// <summary>
    /// ActivityExecutingNotificationHandler
    /// </summary>
    public class ActivityExecutingNotificationHandler : INotificationHandler<ActivityExecuting>
    {
        private readonly ILogger<ActivityExecutingNotificationHandler> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public ActivityExecutingNotificationHandler(ILogger<ActivityExecutingNotificationHandler> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Handle
        /// </summary>
        public async Task HandleAsync(ActivityExecuting notification, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Activity {id} is starting execution.", notification.ActivityExecutionContext.Activity.Id);
            await Task.CompletedTask;
        }
    }

    /// <summary>
    /// ActivityExecutedNotificationHandler
    /// </summary>
    public class ActivityExecutedNotificationHandler : INotificationHandler<ActivityExecuted>
    {
        private readonly ILogger<ActivityExecutedNotificationHandler> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public ActivityExecutedNotificationHandler(ILogger<ActivityExecutedNotificationHandler> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Handle
        /// </summary>
        public async Task HandleAsync(ActivityExecuted notification, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Activity {id} has finished execution.", notification.ActivityExecutionContext.Activity.Id);
            await Task.CompletedTask;
        }
    }

    /// <summary>
    /// WorkflowExecutingNotificationHandler
    /// </summary>
    public class WorkflowExecutingNotificationHandler : INotificationHandler<WorkflowExecuting>
    {
        private readonly ILogger<WorkflowExecutingNotificationHandler> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public WorkflowExecutingNotificationHandler(ILogger<WorkflowExecutingNotificationHandler> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Handle
        /// </summary>
        public async Task HandleAsync(WorkflowExecuting notification, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Workflow {id} is starting execution.", notification.WorkflowExecutionContext.Workflow.Id);
            await Task.CompletedTask;
        }
    }

    /// <summary>
    /// WorkflowExecutedNotificationHandler
    /// </summary>
    public class WorkflowExecutedNotificationHandler : INotificationHandler<WorkflowExecuted>
    {
        private readonly ILogger<WorkflowExecutedNotificationHandler> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public WorkflowExecutedNotificationHandler(ILogger<WorkflowExecutedNotificationHandler> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Handle
        /// </summary>
        public async Task HandleAsync(WorkflowExecuted notification, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Workflow {id} has finished execution.", notification.WorkflowExecutionContext.Workflow.Id);
            await Task.CompletedTask;
        }
    }

    public static class NotifyHandlerExtensions
    {
        public static IServiceCollection  AddWorkfowNotifyHandler(this IServiceCollection services)
        {
            services.AddScoped<INotificationHandler<ActivityExecuting>, ActivityExecutingNotificationHandler>();
            services.AddScoped<INotificationHandler<ActivityExecuted>, ActivityExecutedNotificationHandler>();
            services.AddScoped<INotificationHandler<WorkflowExecuting>, WorkflowExecutingNotificationHandler>();
            services.AddScoped<INotificationHandler<WorkflowExecuted>, WorkflowExecutedNotificationHandler>();
            return services;
        }
    }
}
